<?php

declare(strict_types=1);

namespace App\Service;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Model\FlyTopic;
use App\Model\Moment;
use App\Model\MomentsSpecialSubscribe;
use Hyperf\Database\Model\Model;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;

/**
 * 话题
 * Class FlyTopicService
 * @package App\Service
 */
class FlyTopicService extends BaseService
{
    const TYPE_TOPIC = 1; // 话题
    const TYPE_SPECIAL = 2; // 专题

    /**
     * 获取最新话题
     * @param int $limit 最新条数：默认2条
     * @return array
     */
    public function getNewestTopic($limit = 2): array
    {
        $topic = $this->getModelInstance()
            ->where(['is_show' => 1, 'type' => self::TYPE_TOPIC])
            ->orderBy('sort', 'desc')
            ->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
        return empty($topic) ? [] : $topic->toArray();
    }

    /**
     * 获取专题文章
     * @param int $special_id
     * @return Builder
     */
    public function getSpecialDrByID(int $special_id): Builder
    {
        $special = $this->getModelInstance()
            ->where(['is_show' => 1, 'type' => self::TYPE_SPECIAL])
            ->where(function ($where) use ($special_id) {
                if (!empty($special_id)) {
                    $where->where('special_id', '=', $special_id);
                }
            })
            ->orderBy('sort', 'desc')
            ->orderBy('created_at', 'desc')
            ->first();
        $special_id = empty($special) ? 0 : $special->id;
        // 分页在动态查询动态
        return make(Moment::class)
            ->leftJoin('fly_moments_profiles', 'moment.id', '=', 'fly_moments_profiles.moments_id')
            ->leftJoin('fly_product', 'fly_moments_profiles.product_id', '=', 'fly_product.id')
            ->leftJoin('fly_industry_link', 'fly_product.industry_id', '=', 'fly_industry_link.industry_id')
            ->leftJoin('fly_topic', 'fly_industry_link.link_id', '=', 'fly_topic.id')
            ->groupBy(['fly_moments.id'])
            ->select([
                Db::raw("ANY_VALUE(issue_time) as issue_time"),
                Db::raw("ANY_VALUE(article_title) as article_title"),
                Db::raw("ANY_VALUE(heart_num) as heart_num"),
                Db::raw("ANY_VALUE(review_num) as review_num"),
                Db::raw("ANY_VALUE(star_num) as star_num"),
                Db::raw("ANY_VALUE(video_desc) as video_desc"),
                Db::raw("ANY_VALUE(view_count) as view_count"),
            ])
            ->whereNull('fly_topic.deleted_at')
            ->where(['fly_topic.id' => $special_id, 'fly_topic.is_show' => 1, 'fly_topic.type' => self::TYPE_SPECIAL, 'check_status' => 1, 'fly_moments.is_show' => 1, 'is_illegal' => 0, 'moments_style' => 2]);
    }

    /**
     * 获取话题动态列表
     * @param int $topic_id
     * @return Builder
     */
    public function getTopicDrByID(int $topic_id): Builder
    {
        return make(Moment::class)
            ->leftJoin('fly_topic', 'fly_moments.topic_id', '=', 'fly_topic.id')
            ->where(['fly_moments.is_show' => 1, 'fly_topic.is_show' => 1, 'is_illegal' => 1, 'type' => self::TYPE_TOPIC, 'fly_topic.id' => $topic_id])
            ->whereNull('deleted_at')
            ->groupBy(['fly_moments.id'])
            ->select([
                Db::raw("ANY_VALUE(issue_time) as issue_time"),
                Db::raw("ANY_VALUE(article_title) as article_title"),
                Db::raw("ANY_VALUE(heart_num) as heart_num"),
                Db::raw("ANY_VALUE(review_num) as review_num"),
                Db::raw("ANY_VALUE(star_num) as star_num"),
                Db::raw("ANY_VALUE(video_desc) as video_desc"),
                Db::raw("ANY_VALUE(view_count) as view_count"),
            ]);
    }

    /**
     * 专题订阅
     * @param int $user_id
     * @param array $special_id
     * @return bool
     */
    public function specialSubscribe(int $user_id, array $special_id): bool
    {
        $specials = array_unique($special_id);
        $offset = array_flip($specials);
        $valid_specials = FlyTopic::whereIn('id', $specials)->pluck('id')->toArray();
        if (empty($valid_specials)) {
            throw new BusinessException(ErrorCode::NORMAL_ERROR, '无有效专题');
        }
        try {
            Db::beginTransaction();
            foreach ($valid_specials as $valid_special) {
                Db::table('fly_moments_special_subscribe')->updateOrInsert(
                    ['user_id' => $user_id, 'special_id' => $valid_special],
                    ['create_time' => time(), 'sort' => $offset[$valid_special] ?? 0]
                );
            }
        } catch (\Throwable $exception) {
            Db::rollBack();
            throw new BusinessException(ErrorCode::NORMAL_ERROR, $exception->getMessage());
        }
        Db::commit();
        return true;
    }

    /**
     * 获取我的专题订阅
     * @param int $user_id
     * @return array
     */
    public function getSubscribed(int $user_id): array
    {
        $subscribes = make(MomentsSpecialSubscribe::class)
            ->leftJoin('fly_topic', 'fly_moments_special_subscribe.special_id', '=', 'fly_topic.id')
            ->where(['user_id' => $user_id])
            ->orderBy('sort', 'asc')
            ->select(['id', 'topic_name'])
            ->get();
        return empty($subscribes) ? [] : $subscribes->toArray();
    }

}